package com.phamkhanh.common;

import java.io.File;
import java.util.NoSuchElementException;
import java.util.Scanner;

public class Config {

    private int numVariables;
    private int numEquals;
    private String[] equals;
    private float[] upper;
    private float[] lower;
    Fitness fitness;
    private int maxAge;
    private int population;
    private double pc;
    private double pm;
    private int typeCrossOver;
    private int typeMutation;
    private File currentDirectory;

    public void readInput(String inputText) throws IllegalInputException {

        Scanner in = new Scanner(inputText);
        try {
            // Doc so bien va so phuong trinh
            numVariables = Integer.parseInt(in.nextLine());
            numEquals = Integer.parseInt(in.nextLine());

            // Khoi tao cac thanh phan luu tru thong tin
            equals = new String[numEquals];
            upper = new float[numVariables];
            lower = new float[numVariables];

            // Doc tung dong ung voi tung phuong trinh
            for (int i = 0; i < numEquals; i++) {
                equals[i] = in.nextLine();
            }

            // Doc khoang tim nghiem cua cac bien
            for (int i = 0; i < numVariables; i++) {
                lower[i] = in.nextFloat();
                upper[i] = in.nextFloat();

            }
        } catch (NumberFormatException | NoSuchElementException e) {
            throw new IllegalInputException("Input khong hop le");
        }
    }

    public void configChromo() {
        System.out.println("ConfigChromo");
        // Config cho Chromo 
        Chromo.setUpper(upper);
        Chromo.setLower(lower);
        Chromo.setNumGene(numEquals);
        fitness = new Fitness(numVariables, numEquals, equals);
        
        //filter();
         
        Chromo.setUpper(upper);
        Chromo.setLower(lower);
        Chromo.setFitness(fitness);
        
        System.out.println(this);
    }

    int N = 100;
    float[] h;
    float[] low;
    float[] up;
    
    int dem;
    float[] e;
    int[][] sign;
            
    public void filter() {
        up = new float[numVariables];
        low = new float[numVariables];
        h = new float[numVariables];
        flag = false;
        dem = 0;
        e = new float[numVariables];
        sign  = new int[1 << numVariables][numEquals];
        
        for (int i = 0; i < h.length; i++) {
            h[i] = (upper[i] - lower[i]) / N;
        }
        System.out.println("Vao ham filter");
        chooseDoan(0);
    }
    
    boolean flag = false;
    public void chooseDoan(int i) {
        if(flag) return;
        if (i == numVariables) {
            // Log thong tin chon doan
            System.out.println("Chon xong doan");
            for(int j = 0; j < numVariables; j++){
                System.out.println("Doan thu "+j+" : ["+low[j]+","+up[j]+"]");
            }
            
            
            chooseTuple(0);
            dem = 0;
            printSign();

            if(checkSign()){
                System.out.println("Check sign thanh cong, doan thoa man:");
                for(int j = 0; j < numVariables; j++){
                    System.out.println("["+low[j]+","+up[j]+"]");
                }
                upper = up;
                lower = low;
                flag = true;
            }
        }else
        for (int k = 0; k < N; k++) {
            low[i] = lower[i] + k * h[i];
            up[i] = lower[i] + (k + 1) * h[i];
            chooseDoan(i + 1);
        }
    }
    
    
    public void chooseTuple(int i) {
        if (i == numVariables) {
            // Log thong tin bo e
            System.out.println("Chon xong bo "+ dem);
            for(int m = 0; m < numVariables; m++){
                System.out.println("e"+m+"="+e[m]);
            }
            
            // Xac dinh sign m ham
            for (int j = 0; j < numEquals; j++) {
                // Xac dinh dau cua bo thu dem cho ham j
                sign[dem][j] = fitness.calculateSignFuntion(j, e);
            }
            
            dem++;
            return;
        }
        e[i] = low[i];
        chooseTuple(i + 1);
        e[i] = up[i];
        chooseTuple(i + 1);
    }
    
    public boolean checkSign() {
        for (int i = 0; i < numEquals; i++) { 
            
            for (int j = 0; j < (1 << numVariables); j++) {
                
                
            }
            
        }
        return true;
    }
    
    
    public void printSign(){
        for (int i = 0; i < (1 << numVariables); i++) {
            for (int j = 0; j < numEquals; j++) {
                System.out.print("  "+sign[i][j]);
            }
            System.out.println("");
        }
        System.out.println("\n\n");
    }


    public Config() {
        this.maxAge = 1000;
        this.population = 50;
        this.pc = 0.25;
        this.pm = 0.05;
        this.typeCrossOver = 1;
        this.typeMutation = 1;
        this.currentDirectory = null;
    }
    public int getMaxAge() {
        return maxAge;
    }

    public void setMaxAge(int maxAge) {
        this.maxAge = maxAge;
    }

    public double getPc() {
        return pc;
    }

    public void setPc(double pc) {
        this.pc = pc;
    }

    public double getPm() {
        return pm;
    }

    public void setPm(double pm) {
        this.pm = pm;
    }

    public int getPopulation() {
        return population;
    }

    public void setPopulation(int population) {
        this.population = population;
    }

    public File getCurrentDirectory() {
        return currentDirectory;
    }

    public void setCurrentDirectory(File currentDirectory) {
        this.currentDirectory = currentDirectory;
    }

    public int getTypeCrossOver() {
        return typeCrossOver;
    }

    public void setTypeCrossOver(int typeCrossOver) {
        this.typeCrossOver = typeCrossOver;
    }

    public int getTypeMutation() {
        return typeMutation;
    }

    public void setTypeMutation(int typeMutation) {
        this.typeMutation = typeMutation;
    }

    @Override
    public String toString() {
        return "Config{" + "numVariables=" + numVariables + ", numEquals=" + numEquals + ", equals=" + equals + ", upper=" + upper + ", lower=" + lower + ", maxAge=" + maxAge + ", population=" + population + ", pc=" + pc + ", pm=" + pm + ", typeCrossOver=" + typeCrossOver + ", typeMutation=" + typeMutation + '}';
    }
    
    
}
